package util;

import ejb.facades.extra.ConfigurationFacadeLocal;
import entities.extra.Configuration;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.ConcurrencyManagement;
import static javax.ejb.ConcurrencyManagementType.CONTAINER;
import javax.ejb.EJB;
import javax.ejb.Lock;
import static javax.ejb.LockType.READ;
import static javax.ejb.LockType.WRITE;
import javax.ejb.Schedule;
import javax.ejb.Singleton;
import javax.ejb.Startup;

/**
 * Trabalho PD - 2014/2015
 *
 * @author a21210380 a21210392
 */
@ConcurrencyManagement(CONTAINER)
@Startup
@Singleton
public class Clock {
    //'2015-02-13 10:08:07'
    public final static String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";

    @EJB
    private ConfigurationFacadeLocal configurationFacade;

    private final Calendar calendar;

    public Clock() {
        calendar = Calendar.getInstance();
    }

    @PostConstruct
    public void init() {
        Configuration findSystemTime = configurationFacade.findSystemTime();
        try {
            Date parse = new SimpleDateFormat(DATE_FORMAT).parse(findSystemTime.getValue());
            calendar.setTime(parse);
        } catch (ParseException ex) {
            Logger.getLogger(Clock.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @PreDestroy
    public void save() {
        Configuration findSystemTime = configurationFacade.findSystemTime();
        findSystemTime.setValue(new SimpleDateFormat(DATE_FORMAT).format(calendar.getTime()));
        configurationFacade.edit(findSystemTime);
    }
    
    @Lock(READ)
    public Date getTime() {
        return calendar.getTime();
    }
    
    @Lock(READ)
    public Calendar getCalendar() {
        Calendar instance = Calendar.getInstance();
        instance.setTime(calendar.getTime());
        return instance;
    }
    
    @Schedule(second = "*", minute="*", hour="*")
    @Lock(WRITE)
    public void update() {
        calendar.add(Calendar.SECOND, 1);
    }
    
    @Lock(WRITE)
    public void setTime(Date date) {
        if(date == null) {
            return;
        }
        calendar.setTime(date);
    }

}
